#ifndef __THREAD_HPP__
#define __THREAD_HPP__

#include <iostream>
#include <string>
#include <functional>
#include <unistd.h>

namespace ThreadModule
{
    using func_t = std::function<void(std::string)>;
    static int number = 1;

    // 强枚举类型
    enum class TSTATUS {
        NEW,
        RUNNING,
        STOP,
    };

    class Thread
    {
        // pthread_create函数中无法回调Routine函数,Routine函数还需要传this,所以需要将Routine函数设置为static
        // 但是在Routine函数内无法访问非静态成员变量func,所以可以把this作为参数传给Routine
        static void* Routine(void* args)
        {
            Thread* t = static_cast<Thread*>(args);
            t->_status = TSTATUS::RUNNING;
            t->_func(t->Name());
            return nullptr;
        }
        void EnableDetach() { _joinable = false;}
    public:
        Thread(func_t func)
        :_func(func)
        ,_pid(getpid())
        ,_joinable(true)
        ,_status(TSTATUS::NEW)
        {
            _name = "thread-" + std::to_string(number++);
        }

        bool Start()
        {
            if (_status != TSTATUS::RUNNING)
            {
                int n = ::pthread_create(&_tid, nullptr, Routine, this);
                if (n != 0) return false;
                return true;
            }
            return false;
        }

        bool Stop()
        {
            if (_status != TSTATUS::STOP)
            {
                int n = ::pthread_cancel(_tid);
                if (n != 0) return false;
                _status = TSTATUS::STOP;
                return true;
            }
            return false;
        }

        bool Join()
        {
            if (_joinable)
            {
                int n = ::pthread_join(_tid, nullptr);
                if (n != 0) return false;
                _status = TSTATUS::STOP;
                return true;
            }
            return false;
        }

        void Detach()
        {
            EnableDetach();
            ::pthread_detach(_tid);
        }

        bool IsJoinable() { return _joinable; }
        std::string Name() { return _name; }
        ~Thread()
        {}
    private:
        std::string _name; // 线程名
        pthread_t _tid;    // 线程id
        pid_t _pid;        // 进程id
        bool _joinable;    // 线程是否分离
        func_t _func;      // 回调函数
        TSTATUS _status;   // 线程当前状态
    };

}


// namespace ThreadModule
// {
//     template<typename T>
//     using func_t = std::function<void(T*)>;
//     static int number = 1;

//     // 强枚举类型
//     enum class TSTATUS {
//         NEW,
//         RUNNING,
//         STOP,
//     };

//     template<typename T>
//     class Thread
//     {
//         // using func_t = std::function<void(T*)>; 
//         // pthread_create函数中无法回调Routine函数,Routine函数还需要传this,所以需要将Routine函数设置为static
//         // 但是在Routine函数内无法访问非静态成员变量func,所以可以把this作为参数传给Routine
//         static void* Routine(void* args)
//         {
//             Thread<T>* t = static_cast<Thread<T>*>(args);
//             t->_status = TSTATUS::RUNNING;
//             t->_func(t->_data);
//             return nullptr;
//         }
//         void EnableDetach() { _joinable = false;}
//     public:
//         Thread(func_t<T> func, T* data)
//         :_func(func)
//         ,_pid(getpid())
//         ,_joinable(true)
//         ,_status(TSTATUS::NEW)
//         ,_data(data)
//         {
//             _name = "thread-" + std::to_string(number++);
//         }

//         bool Start()
//         {
//             if (_status != TSTATUS::RUNNING)
//             {
//                 int n = ::pthread_create(&_tid, nullptr, Routine, this);
//                 if (n != 0) return false;
//                 return true;
//             }
//             return false;
//         }

//         bool Stop()
//         {
//             if (_status != TSTATUS::STOP)
//             {
//                 int n = ::pthread_cancel(_tid);
//                 if (n != 0) return false;
//                 _status = TSTATUS::STOP;
//                 return true;
//             }
//             return false;
//         }

//         bool Join()
//         {
//             if (_joinable)
//             {
//                 int n = ::pthread_join(_tid, nullptr);
//                 if (n != 0) return false;
//                 _status = TSTATUS::STOP;
//                 return true;
//             }
//             return false;
//         }

//         void Detach()
//         {
//             EnableDetach();
//             ::pthread_detach(_tid);
//         }

//         bool IsJoinable() { return _joinable; }
//         std::string Name() { return _name; }
//         ~Thread()
//         {}

//         T* getData() {return _data;}
//     private:
//         std::string _name; // 线程名
//         pthread_t _tid;    // 线程id
//         pid_t _pid;        // 进程id
//         bool _joinable;    // 线程是否分离
//         func_t<T> _func;      // 回调函数
//         TSTATUS _status;   // 线程当前状态
//         T* _data;           // 线程数据
//     };

// }


#endif